package com.trip.admin;

import com.trip.admin.datatables.DTInput;
import com.trip.admin.datatables.DTOutput;
import com.trip.api.ControllerResult;
import com.trip.config.CommonProperties;
import com.trip.dao.tables.pojos.PaeTagsDomain;
import com.trip.dao.tables.pojos.PicDomain;
import com.trip.dao.tables.pojos.PlaceAndExpDetailDomain;
import com.trip.dao.tables.pojos.PlaceAndExpDomain;
import com.trip.dao.tables.records.PlaceAndExpRecord;
import com.trip.exception.ServiceException;
import com.trip.service.BasicInfoService;
import com.trip.service.PicService;
import com.trip.service.PlaceAndExperienceService;
import com.trip.vo.PlaceAndExperienceQo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created by hc24 on 2017/12/16.
 */
@RequestMapping("/admin/pae")
@Controller
public class PlaceAndExpAdminController {
    private static final Logger logger= LoggerFactory.getLogger(PlaceAndExpAdminController.class);

    @Autowired
    private PlaceAndExperienceService placeAndExperienceService;

    @Autowired
    private BasicInfoService basicInfoService;

    @Autowired
    private PicService picService;

    @Autowired
    private CommonProperties properties;


    @GetMapping("/list")
    public String list(Model model){
        model.addAttribute("states",basicInfoService.queryStateList());
        return "list";
    }

    @GetMapping("/edit")
    public String edit(Model model,String id){
        if(id!=null){
            model.addAttribute("pae",placeAndExperienceService.querAdminyDetail(id));
        }
        model.addAttribute("tags",basicInfoService.queryTagList(null));
        model.addAttribute("states",basicInfoService.queryStateList());
        return "edit";
    }

    @GetMapping("/editRelated")
    public String editRelated(Model model,String id){
        if(id!=null){
            PlaceAndExpRecord record= placeAndExperienceService.query(id);
            if(record!=null)
                model.addAttribute("pae",record.into(PlaceAndExpDomain.class));
        }
        model.addAttribute("states",basicInfoService.queryStateList());
        return "related";
    }

    @GetMapping
    @ResponseBody
    public DTOutput query(PlaceAndExperienceQo qo, DTInput dtInput){
        return DTOutput.print(dtInput,placeAndExperienceService.queryAdminList(qo,dtInput.getStart(),dtInput.getLength()));
    }

    @GetMapping("/{id}/related")
    @ResponseBody
    public DTOutput queryRelated(@PathVariable String id){
        return DTOutput.print(placeAndExperienceService.queryRelatedAdminList(id));
    }

    @PostMapping("/{id}/related/{relatedId}")
    @ResponseBody
    public ControllerResult addRelated(@PathVariable  String id,@PathVariable String relatedId){
        placeAndExperienceService.addRelated(id,relatedId);
        return ControllerResult.success();
    }

    @DeleteMapping("/{id}/related/{relatedId}")
    @ResponseBody
    public ControllerResult removeRelated(@PathVariable  String id,@PathVariable String relatedId){
        placeAndExperienceService.removeRelated(id,relatedId);
        return ControllerResult.success();
    }

    @DeleteMapping("/{id}")
    @ResponseBody
    public ControllerResult del(@PathVariable  String id){
        placeAndExperienceService.delete(id);
        return ControllerResult.success();
    }

    @PostMapping
    @ResponseBody
    public ControllerResult save(PlaceAndExpDomain pae, String[] tags,String[] picIds,DetailForm detail){
        //if(tags==null)
            //throw new ServiceException("Please choose tags.");
        if(picIds==null)
            throw new ServiceException("Please upload picture.");
        if(pae.getCover()==null)
            throw new ServiceException("Please choose cover.");
        if(detail==null)
            throw new ServiceException("Please input detail info.");

        List<String> tagList=new ArrayList<>();
        if(tags!=null)
            tagList=Arrays.asList(tags);

        List<String> picList=new ArrayList<>();
        if(picIds!=null)
            picList=Arrays.asList(picIds);
        pae.setTags(String.join(",",tagList.stream().map(e->e.toString()).collect(Collectors.toList())));
        pae.setArrivedNumber(0);
        placeAndExperienceService.save(pae,buildPaeTagsDomainList(tagList),picList,buildDetailDomainList(detail));

        return ControllerResult.success();
    }

    @DeleteMapping("/pic/{picId}")
    @ResponseBody
    public ControllerResult delPic(@PathVariable String picId){
        picService.delPic(picId);
        return ControllerResult.success();
    }

    @ApiOperation("Upload plan cover")
    @PostMapping(value = "/pic")
    @ResponseBody
    public ControllerResult<PicDomain> uploadPic(@NotNull MultipartFile file){
        logger.info("receive file:"+file.getOriginalFilename());
        properties.validatePic(file);

        try {
            PicDomain coverPic= picService.savePic(file.getBytes(),file.getOriginalFilename().substring(file.getOriginalFilename().indexOf(".")),1);
            return ControllerResult.success(coverPic);
        } catch (IOException e) {
            throw new ServiceException("IO error, please retry");
        }
    }

    private List<PaeTagsDomain> buildPaeTagsDomainList(List<String> tags){
        return tags.stream().map(e->{
            PaeTagsDomain domain=new PaeTagsDomain();
            domain.setTagCode(e);
            return domain;
        }).collect(Collectors.toList());
    }

    private List<PlaceAndExpDetailDomain> buildDetailDomainList(DetailForm detail){
        List<PlaceAndExpDetailDomain> detailList=new ArrayList<>();

        PlaceAndExpDetailDomain detailDomain1=new PlaceAndExpDetailDomain();
        PlaceAndExpDetailDomain detailDomain2=new PlaceAndExpDetailDomain();
        PlaceAndExpDetailDomain detailDomain3=new PlaceAndExpDetailDomain();
        PlaceAndExpDetailDomain detailDomain4=new PlaceAndExpDetailDomain();
        detailDomain1.setContent(detail.getHoursDescription());
        detailDomain1.setVal(detail.getHours()==null?null:detail.getHours().toString());
        detailDomain1.setType(1);
        detailDomain2.setContent(detail.getGroupSizeDescription());
        detailDomain2.setVal(detail.getGroupSize()==null?null:detail.getGroupSize());
        detailDomain2.setType(2);
        detailDomain3.setContent(detail.getLanguageDescription());
        detailDomain3.setVal(detail.getLanguage());
        detailDomain3.setType(3);
        detailDomain4.setContent(detail.getTransportDescription());
        detailDomain4.setVal(detail.getTransport());
        detailDomain4.setType(4);

        detailList.addAll(Arrays.asList(detailDomain1,detailDomain2,detailDomain3,detailDomain4));
        if(detail.getOtherDetail()==null)
            return detailList;
        for(String other:detail.getOtherDetail()){
            PlaceAndExpDetailDomain detailDomain=new PlaceAndExpDetailDomain();
            detailDomain.setContent(other);
            detailDomain.setType(0);

            detailList.add(detailDomain);
        }

        return detailList;
    }


    public static class DetailForm{
        private Integer hours;
        private String groupSize;
        private String language;
        private String transport;

        private List<String> otherDetail;

        public Integer getHours() {
            return hours;
        }

        public void setHours(Integer hours) {
            this.hours = hours;
        }

        public String getGroupSize() {
            return groupSize;
        }

        public void setGroupSize(String groupSize) {
            this.groupSize = groupSize;
        }

        public String getLanguage() {
            return language;
        }

        public void setLanguage(String language) {
            this.language = language;
        }

        public String getTransport() {
            return transport;
        }

        public void setTransport(String transport) {
            this.transport = transport;
        }

        public List<String> getOtherDetail() {
            return otherDetail;
        }

        public void setOtherDetail(List<String> otherDetail) {
            this.otherDetail = otherDetail;
        }

        public String getHoursDescription(){
            return String.format("%s hours Total",hours);
        }

        public String getGroupSizeDescription(){
            return String.format("Group size up to %s traveller",groupSize);
        }

        public String getLanguageDescription(){
            return String.format("Offered in %s",language);
        }

        public String getTransportDescription(){
            return String.format("Transport by private %s",transport);
        }
    }

}
